#pragma once
using namespace std;
#include "VMPI_Lock.h"

#define WM_USER_TIMER		(WM_USER + 410)

#ifndef _USE_TIMER_OUTSIDE_
class CVirtualDlg;
#endif
class CTimerParam;
class CUserTimer
{
public:
	CUserTimer();
	~CUserTimer();
	void DestroyTimer();
#ifndef _USE_TIMER_OUTSIDE_
	HANDLE SetTimer(CVirtualDlg *caller, UINT_PTR nIDEvent, uintptr_t nElapse, bool runonce);
	HANDLE SetLogTimer(CVirtualDlg *caller, UINT_PTR nIDEvent, uintptr_t nElapse, bool runonce);
	HANDLE SetLogTimer(HWND caller, UINT_PTR nIDEvent, uintptr_t nElapse, bool runonce);
#endif
	HANDLE SetTimer(HWND caller, UINT_PTR nIDEvent, uintptr_t nElapse, bool runonce);
	void KillTimer(HANDLE hThread);
protected:
	vmpi_spin_lock lock_Timer;
	CArray<CTimerParam*, CTimerParam*> m_Timer;

	HANDLE SetTimer(CTimerParam *pParam);
};

class CTimerParam
{
	friend class CUserTimer;
	friend DWORD WINAPI StartThread_Timer(LPVOID p);
protected:
	CTimerParam(
#ifndef _USE_TIMER_OUTSIDE_
		CVirtualDlg *caller,
#endif
		HWND hcaller, UINT_PTR nidevent, uintptr_t nelapse, bool runonce);
	~CTimerParam();

	HANDLE createThread();
	__forceinline void Stop(){ stopThread = true; SetEvent(hEvent); }
	void timerThread();

#ifndef _USE_TIMER_OUTSIDE_
	CVirtualDlg *Caller;
	bool logDispatch;
#endif
	HWND hCaller;
	UINT_PTR nIDEvent;
	uintptr_t nElapse;
	bool runOnce;
	HANDLE hEvent, hThread;
	bool threadRunning, stopThread;
};
